/* plotter.h */

#ifndef DODO_PLOTTER_H
#define DODO_PLOTTER_H

#include <cairomm/cairomm.h>
#include <string>

#include <dodo_plot/kernel/plotfwd.h>
#include <dodo_plot/kernel/basic_elements.h>
#include <dodo_plot/kernel/basic_utils.h>

namespace dodo_plot
{

using Cairo::LINE_CAP_BUTT;
using Cairo::LINE_CAP_ROUND;
using Cairo::LINE_CAP_SQUARE;

using Cairo::LINE_JOIN_BEVEL;
using Cairo::LINE_JOIN_MITER;
using Cairo::LINE_JOIN_ROUND;

using Cairo::LineCap;
using Cairo::LineJoin;

class Plotter
{
public: //Basic actions like cairomm
	//path
	void begin_new_path() const;
	void begin_new_sub_path() const;
	void close_path() const;

	//fill & paint
	void fill() const;
	void fill_preserve() const;
	void paint() const;

	//stroke
	void stroke() const;
	void stroke_preserve() const;

	//move line arc, etc
	void move_to(double x, double y) const;
	void move_to(const Point& p) const;
	void line_to(double x, double y) const;
	void line_to(const Point& p) const;
	void rel_move_to(double x, double y) const;
	void rel_move_to(const Point& offset) const;
	void rel_line_to(double x, double y) const;
	void rel_line_to(const Point& offset) const;
	
	void abs_move_to(double x, double y) const;
	void abs_move_to(const Point& p) const;
	void abs_line_to(double x, double y) const;
	void abs_line_to(const Point& p) const;
	void abs_rel_move_to(double x, double y) const;
	void abs_rel_move_to(const Point& offset) const;
	void abs_rel_line_to(double x, double y) const;
	void abs_rel_line_to(const Point& offset) const;
	//TODO: arc

	void rectangle(const Position& pos) const;
	void rectangle(const Point& topleft, double w, double h) const;
	void rectangle(const Point& p1, const Point& p2) const;

	void abs_rectangle(const Position& pos) const;
	void abs_rectangle(const Point& topleft, double w, double h) const;
	void abs_rectangle(const Point& p1, const Point& p2) const;
	//font & text
	void set_font(const Font& font) const;
	void set_font_size(double size) const;
	void show_text(const std::string& text) const;

	//
	Point get_current_point() const;

	void clip() const;
	void reset_clip() const;
	
	void rotate(double rad_degrees) const;
	void rotate_degrees(double degrees) const;
	//
	//line
	void set_line_width(double width) const;
	void set_line_cap(LineCap mode) const;
	void set_line_join(LineJoin mode) const;
	//source
	void set_color(const Color& color) const;
//	void set_source() const;
	//
	void save() const;
	void restore() const;

public:
	Context_p get_cr() const;
	Plotter sub_plotter(const Position& sub_pos, const Position& sub_local_pos) const;
	Point get_abs_point(double x, double y) const;
	Point get_abs_point(const Point& point) const;
public:
	template <class Proj_T>
	void move_to(const Point& p, const Proj_T extra_proj) const;

	template <class Proj_T>
	void line_to(const Point& p, const Proj_T extra_proj) const;

	// take care with this one.
	template <class Proj_T>
	void rel_line_to(const Point& p, const Proj_T extra_proj) const;


	void move_to_direction(double absolute_length, double degree) const;
	void line_to_direction(double absolute_length, double degree) const;

	void line(const Point& p1, const Point& p2) const;

	template <class Proj_T>
	void line(const Point& p1, const Point& p2, const Proj_T& extra_proj) const;

	//*Iter should be Point
	template <class Iter>
	void polyline(Iter b, Iter e) const;
	
	template <class Iter, class Proj_T>
	void polyline(Iter b, Iter e, const Proj_T& extra_proj) const;

	template <class Iter>
	void polygon(Iter b, Iter e) const;

	template <class Iter, class Proj_T>
	void polygon(Iter b, Iter e, const Proj_T& extra_proj) const;

	//*Iter should be a container for Points
	template <class Iter>
	void polypolygon(Iter b, Iter e) const;

	template <class Iter, class Proj_T>
	void polypolygon(Iter b, Iter e, const Proj_T& extra_proj) const;

public:
//	double width() const { return w_};
//	double height() const { return h_};
public:
	Plotter(Context_p cr, const Position& given_pos, const Position& local_pos);
private:
	mutable Context_p cr_;
	Pos_Projection proj_;
//	double w_, double h_;
};

}

#include <dodo_plot/kernel/plotter.tcc>

#endif //DODO_PLOTTER_H

